# 读入excel数据
import pymysql
import xlrd
# 使用numpy库
import numpy as np
# 使用深拷贝
from copy import deepcopy
# 使用绘图功能
import matplotlib.pyplot as plt
# 遗传算法库
from deap import base, tools, creator, algorithms
# 随机数
import random

"""
注意：客户数组元素从0开始
"""


class ga_algorithm(object):

    def __init__(self):
        self.stats = tools.Statistics(key=lambda ind: ind.fitness.values)
        self.toolbox = base.Toolbox()
        self.data_dict = {'NodesInfo': [(1, 8.824934894), (2, 7.375587827), (3, 8.623492053), (4, 4.471793255),
                                        (5, 2.352144673), (6, 6.803964745), (7, 8.609318416), (8, 8.918722585),
                                        (9, 1.714122873), (10, 9.170470094), (11, 8.360166861), (12, 3.944794957),
                                        (13, 2.386734317), (14, 1.278249076), (15, 6.212404481), (16, 1.261608653),
                                        (17, 8.307934651), (18, 5.823108579), (19, 3.223684224), (20, 9.157723472),
                                        (21, 3.426481623), (22, 2.493208655), (23, 8.919128299), (24, 3.698778273),
                                        (25, 8.065164784), (26, 2.408542568), (27, 1.644974593), (28, 2.498521597)],
                          'CarIsChangeAble': False, 'CarIsNotChangeAble': True, 'CarNumSet': 5, 'OneTypeCar': True,
                          'TwoTypeCar': False, 'Load_1': 5, 'Load_2': 5, 'CarSpeed': 51, 'UnloadTime': 5,
                          'TimeLimit': 5, 'LengthLimit': 80, 'GenerationsNumber': 200,
                          'distance_matrix': [[0.0, 26216.0, 26303.0, 25070.0, 23408.0, 22864.0, 20092.0, 23521.0,
                                               9600.0, 9293.0, 3966.0, 21181.0, 9822.0, 10753.0, 11062.0, 12070.0,
                                               17009.0, 15759.0, 19100.0, 16014.0, 18091.0, 14446.0, 14986.0,
                                               14708.0, 14334.0, 18566.0, 18412.0, 24335.0, 24881.0],
                                              [28378.0, 0.0, 1379.0, 6214.0, 7707.0, 7457.0, 9114.0, 16153.0, 21412.0,
                                               21105.0, 28879.0, 13813.0, 25516.0, 28856.0, 32843.0, 30173.0, 35343.0,
                                               31932.0, 28588.0, 34122.0, 36240.0, 36719.0, 37259.0, 36981.0, 36607.0,
                                               37999.0, 32241.0, 40559.0, 41105.0],
                                              [26283.0, 1491.0, 0.0, 4119.0, 5612.0, 5362.0, 7019.0, 14058.0, 19317.0,
                                               19010.0, 26784.0, 11718.0, 23421.0, 26761.0, 30748.0, 28078.0, 33248.0,
                                               29837.0, 26493.0, 32027.0, 34145.0, 34624.0, 35164.0, 34886.0, 34512.0,
                                               35904.0, 30146.0, 38464.0, 39010.0],
                                              [25050.0, 6345.0, 4066.0, 0.0, 3102.0, 4129.0, 5786.0, 12825.0, 18084.0,
                                               17777.0, 25551.0, 10485.0, 22188.0, 25528.0, 29515.0, 26845.0, 32015.0,
                                               28604.0, 25260.0, 30794.0, 32912.0, 33391.0, 33931.0, 33653.0, 33279.0,
                                               34671.0, 28913.0, 37231.0, 37777.0],
                                              [23640.0, 7649.0, 5370.0, 2775.0, 0.0, 4122.0, 4376.0, 11415.0, 16674.0,
                                               16367.0, 24141.0, 9075.0, 20778.0, 24118.0, 28105.0, 25435.0, 30605.0,
                                               27194.0, 23850.0, 29384.0, 31502.0, 31981.0, 32521.0, 32243.0, 31869.0,
                                               33261.0, 27503.0, 35821.0, 36367.0],
                                              [22627.0, 7424.0, 5145.0, 3912.0, 3409.0, 0.0, 3363.0, 10402.0, 15661.0,
                                               15354.0, 23128.0, 8062.0, 19765.0, 23105.0, 27092.0, 24422.0, 29592.0,
                                               26181.0, 22837.0, 28371.0, 30489.0, 30968.0, 31508.0, 31230.0, 30856.0,
                                               32248.0, 26490.0, 34808.0, 35354.0],
                                              [20561.0, 9080.0, 6801.0, 5568.0, 3906.0, 3362.0, 0.0, 8336.0, 13595.0,
                                               13288.0, 21062.0, 5996.0, 17699.0, 21039.0, 25026.0, 22356.0, 27526.0,
                                               24115.0, 20771.0, 26305.0, 28423.0, 28902.0, 29442.0, 29164.0, 28790.0,
                                               30182.0, 24424.0, 32742.0, 33288.0],
                                              [22939.0, 16126.0, 13847.0, 12614.0, 10952.0, 10408.0, 8391.0, 0.0,
                                               15973.0, 15666.0, 23440.0, 6596.0, 20077.0, 21639.0, 27404.0, 22956.0,
                                               29904.0, 24715.0, 21371.0, 28683.0, 30801.0, 31280.0, 31820.0, 31542.0,
                                               31168.0, 32560.0, 25024.0, 48938.0, 49484.0],
                                              [9941.0, 19702.0, 17423.0, 16190.0, 14528.0, 13984.0, 11967.0, 14641.0,
                                               0.0, 889.0, 9778.0, 12301.0, 6194.0, 9441.0, 14713.0, 10758.0, 17213.0,
                                               12536.0, 14230.0, 15992.0, 18110.0, 20271.0, 20811.0, 20533.0, 20159.0,
                                               19869.0, 15916.0, 30160.0, 30706.0],
                                              [9114.0, 20471.0, 18192.0, 16959.0, 15297.0, 14753.0, 12736.0, 15410.0,
                                               875.0, 0.0, 8951.0, 13070.0, 5367.0, 8614.0, 13886.0, 9931.0, 16386.0,
                                               11709.0, 14128.0, 15165.0, 17283.0, 19444.0, 19984.0, 19706.0, 19332.0,
                                               19042.0, 14040.0, 29333.0, 29879.0],
                                              [5442.0, 27201.0, 27288.0, 26055.0, 24393.0, 23849.0, 21077.0, 24506.0,
                                               10585.0, 10278.0, 0.0, 22166.0, 9151.0, 10018.0, 8961.0, 11335.0,
                                               13880.0, 15024.0, 18365.0, 10240.0, 12358.0, 13838.0, 14378.0, 14100.0,
                                               13726.0, 14117.0, 17804.0, 23727.0, 24273.0],
                                              [21631.0, 14818.0, 12539.0, 11306.0, 9644.0, 9100.0, 7083.0, 7628.0,
                                               14665.0, 14358.0, 22132.0, 0.0, 16671.0, 15044.0, 23288.0, 16361.0,
                                               25788.0, 18120.0, 14776.0, 24296.0, 26885.0, 24064.0, 24604.0, 24326.0,
                                               23952.0, 28184.0, 18429.0, 42343.0, 42889.0],
                                              [10138.0, 25351.0, 23072.0, 21839.0, 20177.0, 19633.0, 17616.0, 20290.0,
                                               6163.0, 5856.0, 9945.0, 17703.0, 0.0, 4113.0, 11294.0, 5430.0, 13794.0,
                                               7208.0, 10528.0, 13365.0, 14691.0, 13133.0, 13673.0, 13395.0, 13021.0,
                                               16450.0, 9539.0, 19010.0, 19556.0],
                                              [10477.0, 28816.0, 26537.0, 25304.0, 23642.0, 23098.0, 21081.0, 21626.0,
                                               9413.0, 9106.0, 10022.0, 16102.0, 4135.0, 0.0, 8985.0, 1518.0, 11485.0,
                                               5262.0, 9088.0, 9419.0, 12008.0, 9187.0, 9727.0, 9449.0, 9075.0, 13307.0,
                                               7593.0, 16148.0, 16694.0],
                                              [12567.0, 32864.0, 30585.0, 29352.0, 27690.0, 27146.0, 25129.0, 27803.0,
                                               14848.0, 14541.0, 8616.0, 24536.0, 10905.0, 9175.0, 0.0, 9247.0, 2803.0,
                                               12302.0, 15529.0, 3776.0, 4997.0, 5444.0, 5130.0, 6143.0, 7058.0, 6756.0,
                                               14633.0, 9316.0, 9862.0],
                                              [11793.0, 30132.0, 27853.0, 26620.0, 24958.0, 24414.0, 22397.0, 22942.0,
                                               10729.0, 10422.0, 11338.0, 17418.0, 5451.0, 1517.0, 9070.0, 0.0, 11724.0,
                                               4295.0, 7522.0, 9214.0, 11803.0, 8982.0, 9522.0, 9244.0, 8870.0, 13102.0,
                                               6626.0, 15943.0, 16489.0],
                                              [14602.0, 34899.0, 32620.0, 31387.0, 29725.0, 29181.0, 27164.0, 29838.0,
                                               16883.0, 16576.0, 10651.0, 26571.0, 12940.0, 11210.0, 3405.0, 11282.0,
                                               0.0, 14337.0, 17564.0, 5378.0, 5053.0, 7056.0, 6742.0, 7755.0, 8670.0,
                                               7049.0, 15961.0, 6624.0, 8303.0],
                                              [15456.0, 31905.0, 29626.0, 28393.0, 26731.0, 26187.0, 24170.0, 24715.0,
                                               12515.0, 12208.0, 15001.0, 19191.0, 7237.0, 5262.0, 12127.0, 4297.0,
                                               14781.0, 0.0, 5226.0, 10890.0, 13479.0, 10822.0, 11362.0, 11084.0,
                                               10710.0, 14942.0, 4565.0, 17783.0, 18329.0],
                                              [19139.0, 28398.0, 26119.0, 24886.0, 23224.0, 22680.0, 20663.0, 21208.0,
                                               16031.0, 15724.0, 18684.0, 15684.0, 10899.0, 8462.0, 15674.0, 7844.0,
                                               18328.0, 5382.0, 0.0, 14986.0, 16029.0, 12384.0, 12924.0, 12646.0,
                                               12272.0, 16504.0, 5634.0, 19345.0, 19891.0],
                                              [13968.0, 34265.0, 31986.0, 30753.0, 29091.0, 28547.0, 26530.0, 29204.0,
                                               16249.0, 15942.0, 10017.0, 25507.0, 13540.0, 9550.0, 3459.0, 9475.0,
                                               5560.0, 11209.0, 12961.0, 0.0, 3014.0, 2318.0, 2004.0, 3017.0, 3932.0,
                                               4811.0, 11223.0, 7371.0, 7917.0],
                                              [15476.0, 35773.0, 33494.0, 32261.0, 30599.0, 30055.0, 28038.0, 30712.0,
                                               17757.0, 17450.0, 11525.0, 27382.0, 15415.0, 11425.0, 4279.0, 11235.0,
                                               5503.0, 13065.0, 13654.0, 2347.0, 0.0, 3011.0, 2697.0, 3710.0, 4625.0,
                                               2797.0, 11916.0, 5357.0, 5903.0],
                                              [14947.0, 35367.0, 33088.0, 31855.0, 30193.0, 29649.0, 27632.0, 30571.0,
                                               17351.0, 17044.0, 10350.0, 25047.0, 13080.0, 9090.0, 5629.0, 8900.0,
                                               7956.0, 10730.0, 11319.0, 2681.0, 4758.0, 0.0, 1653.0, 1375.0, 2290.0,
                                               5233.0, 9581.0, 8074.0, 8620.0],
                                              [15011.0, 35308.0, 33029.0, 31796.0, 30134.0, 29590.0, 27573.0, 31890.0,
                                               17292.0, 16985.0, 11669.0, 26366.0, 14399.0, 10409.0, 4512.0, 10219.0,
                                               6839.0, 12049.0, 12638.0, 1564.0, 3641.0, 1995.0, 0.0, 2694.0, 3609.0,
                                               4116.0, 10900.0, 6957.0, 7503.0],
                                              [15554.0, 35974.0, 33695.0, 32462.0, 30800.0, 30256.0, 28239.0, 31178.0,
                                               17958.0, 17651.0, 10957.0, 25654.0, 13687.0, 9697.0, 5304.0, 9507.0,
                                               7631.0, 11337.0, 11926.0, 2356.0, 4433.0, 1283.0, 1328.0, 0.0, 326.0,
                                               4908.0, 10188.0, 7749.0, 8295.0],
                                              [15485.0, 35905.0, 33626.0, 32393.0, 30731.0, 30187.0, 28170.0, 31109.0,
                                               17889.0, 17582.0, 10888.0, 25585.0, 13618.0, 9628.0, 5730.0, 9438.0,
                                               8057.0, 11268.0, 11857.0, 2782.0, 4859.0, 1214.0, 1754.0, 562.0, 0.0,
                                               5334.0, 10119.0, 8175.0, 8721.0],
                                              [16173.0, 36470.0, 34191.0, 32958.0, 31296.0, 30752.0, 28735.0, 31409.0,
                                               18454.0, 18147.0, 12222.0, 28078.0, 16111.0, 12121.0, 4976.0, 11931.0,
                                               6756.0, 13761.0, 14350.0, 3043.0, 3558.0, 3707.0, 3393.0, 3306.0, 3632.0,
                                               0.0, 12612.0, 4946.0, 5492.0],
                                              [16765.0, 32028.0, 29749.0, 28516.0, 26854.0, 26310.0, 24293.0, 24838.0,
                                               14641.0, 14334.0, 16725.0, 19314.0, 9363.0, 6394.0, 13519.0, 5776.0,
                                               15846.0, 4360.0, 5303.0, 10571.0, 12648.0, 9003.0, 9543.0, 9265.0,
                                               8891.0, 13123.0, 0.0, 15964.0, 16510.0],
                                              [19899.0, 40196.0, 37917.0, 36684.0, 35022.0, 34478.0, 32461.0, 35135.0,
                                               22180.0, 21873.0, 15948.0, 43297.0, 18237.0, 15901.0, 8702.0, 15711.0,
                                               8676.0, 17541.0, 18130.0, 6898.0, 5484.0, 7487.0, 7173.0, 8186.0, 9101.0,
                                               4142.0, 16392.0, 0.0, 688.0],
                                              [20445.0, 40742.0, 38463.0, 37230.0, 35568.0, 35024.0, 33007.0, 35681.0,
                                               22726.0, 22419.0, 16494.0, 43843.0, 18783.0, 16447.0, 9248.0, 16257.0,
                                               9222.0, 18087.0, 18676.0, 7444.0, 6030.0, 8033.0, 7719.0, 8732.0, 9647.0,
                                               4688.0, 16938.0, 688.0, 0.0]]}

    """生成个体"""

    def get_individual(self):
        nCustomer = len(self.data_dict['NodesInfo'])  # 顾客数量
        perm = np.random.permutation(nCustomer) + 1  # 生成顾客的随机排列,注意顾客编号为1--n
        Perm = []
        for i in range(0, len(perm)):
            Perm.append(perm[i])
        StartNode = []
        while len(StartNode) < self.data_dict['CarNumSet'] - 2:
            Zero_Location = np.random.randint(1, len(Perm))

            if Zero_Location not in StartNode:
                StartNode.append(Zero_Location)
            else:
                pass
        # 将路线片段合并为染色体
        StartNode.sort()
        StartNode.reverse()
        ind = [0]
        for eachLocation in StartNode:
            Perm.insert(eachLocation, 0)

        for j in range(0, len(Perm)):
            ind.append(Perm[j])

        ind.append(0)
        return ind

    """染色体解码，每条路径都是以0为开头与结尾"""

    def decode_individual(self, ind):

        indCopy = np.array(deepcopy(ind))  # 复制ind，防止直接对染色体进行改动
        idxList = list(range(len(indCopy)))
        zeroIdx = np.asarray(idxList)[indCopy == 0]
        routes = []
        for i, j in zip(zeroIdx[0::], zeroIdx[1::]):
            routes.append(ind[i:j] + [0])
        return routes

    """计算两个数组下标（pos1，pos2）所对应的网点id（id1，id2）之间的最短驾驶距离"""

    def calculate_distance(self, pos1, pos2):

        distance = self.data_dict['distance_matrix'][pos1][pos2] / 1000

        return distance

    """计算一个解决方案（染色体中）每条路径的配送距离"""

    def calculate_each_route_length(self, routes):

        Length = []
        for everyRoute in routes:
            # 从每条路径中抽取相邻两个节点，计算节点距离并进行累加
            Distance = 0
            for m, n in zip(everyRoute, everyRoute[1::]):
                Distance += self.calculate_distance(m, n)
            Length.append(Distance)
        return Length

    """计算一个解决方案（染色体中）的总配送距离"""

    def calculate_total_route_length(self, routes):

        totalDistance = 0  # 记录各条路线的总长度
        for eachRoute in routes:
            # 从每条路径中抽取相邻两个节点，计算节点距离并进行累加
            for i, j in zip(eachRoute, eachRoute[1::]):
                totalDistance += self.calculate_distance(i, j)
        return totalDistance

    """计算每条路径的工作时间，返回时间数组"""

    def calculate_each_route_work_time(self, routes):
        routes_length = self.calculate_each_route_length(routes)
        work_times = []
        for i in range(0, len(routes_length)):
            work_time = (routes_length[i] / self.data_dict['CarSpeed']) \
                        + \
                        (self.data_dict['UnloadTime'] / 60) * (len(routes[i]) - 2)

            # 驾驶时间 + 卸货时间
            work_times.append(work_time)
        return work_times

    """计算每条路径的负载，返回负载数组"""

    def calculate_each_route_load(self, routes):
        loads = []
        for each_route in routes:
            load = 0
            for j in range(0, len(each_route)):
                if each_route[j] == 0:
                    pass
                else:
                    load += self.data_dict['NodesInfo'][each_route[j] - 1][1] / 10
            loads.append(load)
        return loads

    """设置超额惩罚"""

    def load_penalty(self, routes):
        penalty = 0
        # 计算每条路径的负载，取max(0, （route_load - maxLoad）*10)计入惩罚项
        # 计算每条路径的距离，时间=（非0节点数*5 + 总距离/速度），取max(0，（WorkTime - maxWorkTime）*10)计入惩罚项

        route_load = self.calculate_each_route_load(routes)
        for each_route_load in route_load:
            penalty += max(0, (each_route_load - self.data_dict['Load_1']) * 10)

        routes_work_time = self.calculate_each_route_work_time(routes)
        for each_route_work_time in routes_work_time:
            penalty += max(0, (each_route_work_time - self.data_dict['TimeLimit']) * 10)

        return penalty

    """综合判断函数（里程+惩罚）"""

    def evaluate(self, individual):
        routes = self.decode_individual(individual)  # 将个体解码为路线
        total_distance = self.calculate_total_route_length(routes)
        return total_distance + self.load_penalty(routes),

    """交叉操作"""

    def get_child(self, ind1, ind2, n_trail=5):
        # 在ind1中随机选择一段子路径subroute1，将其前置
        routes1 = self.decode_individual(ind1)  # 将ind1解码成路径
        num_subroute1 = len(routes1)  # 子路径数量
        subroute1 = routes1[np.random.randint(0, num_subroute1)]
        # 将subroute1中没有出现的顾客按照其在ind2中的顺序排列成一个序列
        unvisited = set(ind1) - set(subroute1)  # 在subroute1中没有出现访问的顾客
        unvisitedPerm = [digit for digit in ind2 if digit in unvisited]  # 按照在ind2中的顺序排列
        # 多次重复随机打断，选取适应度最好的个体
        bestRoute = None  # 容器
        bestFit = np.inf
        for x in range(n_trail):
            # 将该序列随机打断为numSubroute1-1条子路径
            breakPos = [0] + random.sample(range(1, len(unvisitedPerm)), num_subroute1 - 2)  # 产生numSubroute1-2个断点
            breakPos.sort()
            breakSubroute = []
            for i, j in zip(breakPos[0::], breakPos[1::]):
                breakSubroute.append([0] + unvisitedPerm[i:j] + [0])
            breakSubroute.append([0] + unvisitedPerm[j:] + [0])
            # 更新适应度最佳的打断方式
            # 将先前取出的subroute1添加入打断结果，得到完整的配送方案
            breakSubroute.append(subroute1)
            # 评价生成的子路径
            routesFit = self.calculate_total_route_length(breakSubroute) + self.load_penalty(breakSubroute)
            if routesFit < bestFit:
                bestRoute = breakSubroute
                bestFit = routesFit
        # 将得到的适应度最佳路径bestRoute合并为一个染色体
        child = []
        for eachRoute in bestRoute:
            child += eachRoute[:-1]
        return child + [0]

    def crossover(self, ind1, ind2):
        ind1[:], ind2[:] = self.get_child(ind1, ind2), self.get_child(ind2, ind1)
        return ind1, ind2

    """突变操作"""

    def opt(self, route, k=2):
        # 用2-opt算法优化路径
        # 输入：
        # route -- sequence，记录路径
        # 输出： 优化后的路径optimizedRoute及其路径长度
        nCities = len(route)  # 城市数
        optimizedRoute = route  # 最优路径
        minDistance = self.calculate_total_route_length([route])  # 最优路径长度
        for i in range(1, nCities - 2):
            for j in range(i + k, nCities):
                if j - i == 1:
                    continue
                reversedRoute = route[:i] + route[i:j][::-1] + route[j:]  # 翻转后的路径
                reversedRouteDist = self.calculate_total_route_length([reversedRoute])
                # 如果翻转后路径更优，则更新最优解
                if reversedRouteDist < minDistance:
                    minDistance = reversedRouteDist
                    optimizedRoute = reversedRoute
        return optimizedRoute

    def mutate(self, ind):
        """
        用2-opt算法对各条子路径进行局部优化
        """
        routes = self.decode_individual(ind)
        optimizedAssembly = []
        for eachRoute in routes:
            optimizedRoute = self.opt(eachRoute)
            optimizedAssembly.append(optimizedRoute)
        # 将路径重新组装为染色体
        child = []
        for eachRoute in optimizedAssembly:
            child += eachRoute[:-1]
        ind[:] = child + [0]
        return ind,

    """遗传算法开始"""

    def register(self):
        creator.create('FitnessMin', base.Fitness, weights=(-1.0,))  # 最小化问题
        # 给个体一个routes属性用来记录其表示的路线
        creator.create('Individual', list, fitness=creator.FitnessMin)

        # 注册遗传算法操作
        self.toolbox.register('individual', tools.initIterate, creator.Individual, self.get_individual)
        self.toolbox.register('population', tools.initRepeat, list, self.toolbox.individual)
        self.toolbox.register('evaluate', self.evaluate)
        self.toolbox.register('select', tools.selTournament, tournsize=2)
        self.toolbox.register('mate', self.crossover)
        self.toolbox.register('mutate', self.mutate)

        # 生成初始族群
        self.toolbox.popSize = 100

        # 记录迭代数据
        self.stats.register('min', np.min)
        self.stats.register('avg', np.mean)
        self.stats.register('std', np.std)

        # 遗传算法参数
        self.toolbox.ngen = self.data_dict['GenerationsNumber']
        self.toolbox.cxpb = 0.8
        self.toolbox.mutpb = 0.1

    def ga_main(self):
        # 遗传算法主程序
        self.register()

        pop = self.toolbox.population(self.toolbox.popSize)
        hallOfFame = tools.HallOfFame(maxsize=1)
        pop, logs = algorithms.eaMuPlusLambda(pop, self.toolbox, mu=self.toolbox.popSize,
                                              lambda_=self.toolbox.popSize,
                                              cxpb=self.toolbox.cxpb, mutpb=self.toolbox.mutpb,
                                              ngen=self.toolbox.ngen, stats=self.stats,
                                              halloffame=hallOfFame, verbose=True)

        best_individual = hallOfFame.items[0]
        decode_best_individual = self.decode_individual(best_individual)

        return_data = []
        route_time = self.calculate_each_route_work_time(decode_best_individual)
        route_load = self.calculate_each_route_load(decode_best_individual)
        route_length = self.calculate_each_route_length(decode_best_individual)

        # 画出迭代图xcc
        minFit = logs.select('min')
        avgFit = logs.select('avg')
        plt.plot(minFit, 'b-', label='Minimum Fitness')
        plt.plot(avgFit, 'r-', label='Average Fitness')
        plt.xlabel('# Gen')
        plt.ylabel('Fitness')
        plt.legend(loc='best')
        plt.show()

        for each_route in decode_best_individual:
            return_data_sub = []
            for i in range(0, len(each_route)):
                if each_route[i] == 0:
                    return_data_sub.append(0)
                else:
                    return_data_sub.append(self.data_dict['NodesInfo'][each_route[i] - 1][0])
            return_data.append(return_data_sub)

        return return_data, route_time, route_load, route_length


if __name__ == '__main__':
    a = ga_algorithm()
    a.ga_main()
